﻿using AduSkin.Controls;
using AduSkin.Controls.Metro;
using DBMC_Core;
using Microsoft.Win32;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MEMORYSTATUSEX
{
    public uint dwLength;
    public uint dwMemoryLoad;
    public ulong ullTotalPhys;
    public ulong ullAvailPhys;
    public ulong ullTotalPageFile;
    public ulong ullAvailPageFile;
    public ulong ullTotalVirtual;
    public ulong ullAvailVirtual;
    public ulong ullAvailExtendedVirtual;
    public MEMORYSTATUSEX()
    {
        this.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
    }
}

public class MemoryMetrics
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);

    public static void GetMemoryStatus(out int totalMemoryInMb, out int availableMemoryInMb)
    {
        MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX();
        if (GlobalMemoryStatusEx(memStatus))
        {
            totalMemoryInMb = Convert.ToInt32(memStatus.ullTotalPhys / (1024.0 * 1024.0));
            availableMemoryInMb = Convert.ToInt32(memStatus.ullAvailPhys / (1024.0 * 1024.0));
        }
        else
        {
            totalMemoryInMb = 0;
            availableMemoryInMb = 0;
        }
    }
}

namespace DBMC
{
    /// <summary>
    /// Settings.xaml 的交互逻辑
    /// </summary>
    public partial class Settings : Window
    {
        private bool isDragging;
        private Point startPoint;
        public Minecraft minecraft = new Minecraft();
        Danbai danbai = new Danbai();
        LauncherCore launcherCore = new LauncherCore();
        string JavafilePath;
        RootObject dbmcData;

        public Settings()
        {
            InitializeComponent();
            Loaded +=  delegate {  LauncherCore.WriteLog($"启动器核心：设置 - 窗口打开正常"); };
            Load();
            MemoryMetrics.GetMemoryStatus(out int totalMemory, out int availableMemory);
            MemorySettings_UseSilder.Maximum = totalMemory;
            MemorySettings_Max.Text = $"{totalMemory} MB";
            MemorySettings_Current.Text = $"{availableMemory} MB";
        }

        private void Load()
        {
            if (launcherCore.ConfigFileExists)
            {
                LauncherCore.WriteLog($"启动器核心：设置 - 已获取配置文件，获取信息中...");
                string jsonData = File.ReadAllText(launcherCore.ConfigFile);
                dbmcData = JsonConvert.DeserializeObject<RootObject>(jsonData);
                switch (dbmcData.UseJavaOptions)
                {
                    case 0:
                        enableDefaultJavaPath.IsChecked = true;
                        break;
                    case 1:
                        enableSystemJavaPath.IsChecked = true;
                        break;
                    case 2:
                        enableCustomJavaPath.IsChecked = true;
                        break;
                    default:
                        enableDefaultJavaPath.IsChecked = true;
                        break;
                }
                JavaPath.Text = dbmcData.JavaPath;
                MemorySettings_UseSilder.Value = dbmcData.UseMemory;
                MemorySettings_Use.Text = $"{dbmcData.UseMemory} MB";
                LauncherSettings_StartTools.IsChecked = dbmcData.StartTools;
                LauncherSettings_StartTopmost.IsChecked = dbmcData.StartTopmost;
                LauncherSettings_GameTips.IsChecked = dbmcData.GameTips;

                LauncherCore.WriteLog($"启动器核心：设置 - 获取信息成功，当前配置信息：Java：{dbmcData.UseJavaOptions}，Java位置：{JavafilePath ?? "未设置"}，内存：{MemorySettings_Use.Text}，启动页面置顶：{LauncherSettings_StartTopmost.IsChecked}，造图小工具：{LauncherSettings_StartTools.IsChecked}，游戏提示工具：{LauncherSettings_GameTips.IsChecked}");
            }
            else
            {
                LauncherCore.WriteLog($"启动器核心：设置 - 未找到配置文件");
                MessageBox.Show("错误，未找到配置文件");
                Close();
            }
        }

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            isDragging = true;
            startPoint = e.GetPosition(this);
        }

        private void Window_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                Point currentPoint = e.GetPosition(this);
                this.Left += currentPoint.X - startPoint.X;
                this.Top += currentPoint.Y - startPoint.Y;
            }
        }

        private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            isDragging = false;
        }

        private void ExitApp_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void SetJavaPath_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Filter = "Java.exe|java.exe",
                Title = "选择 Java.exe"
            };

            bool? result = openFileDialog.ShowDialog();

            if (result == true)
            {
                string fileName = openFileDialog.FileName;
                if (!minecraft.CheckUseJavaVersion(fileName))
                {
                    MessageBox.Show("Java版本不对", null, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
                JavafilePath = fileName;
                JavaPath.Text = fileName;
            }
        }

        private void Save_Click(object sender, RoutedEventArgs e)
        {
            if (enableDefaultJavaPath.IsChecked == true)
            {
                UseJavaPath(0);
            }
            else if (enableSystemJavaPath.IsChecked == true)
            {
                UseJavaPath(1);
            }
            else if (enableCustomJavaPath.IsChecked == true)
            {
                if (JavafilePath != "" || JavafilePath != null)
                {
                    UpdateJavaPathInJson(JavafilePath);
                    UseJavaPath(2);
                }
            }
            if (Math.Round(MemorySettings_UseSilder.Value) > 0)
            {
                UseUseMemory(Convert.ToInt32(MemorySettings_UseSilder.Value));
            }
            UpdateStartTopmost((bool)LauncherSettings_StartTopmost.IsChecked);
            UpdateStartTools((bool)LauncherSettings_StartTools.IsChecked);
            UpdateGameTips((bool)LauncherSettings_GameTips.IsChecked);
            LauncherCore.WriteLog($"启动器核心：设置 - 设置已保存");
            NoticeManager.NotificationShow.AddNotification(new NotificationModel()
            {
                Title = "通知",
                Content = "设置已保存",
                NotificationType = EnumPromptType.Success
            });
            DialogResult = true;
            Close();
        }

        private void UseJavaPath(int type)
        {
            RootObject dbmcData;

            if (launcherCore.ConfigFileExists)
            {
                string jsonData = File.ReadAllText(launcherCore.ConfigFile);
                dbmcData = JsonConvert.DeserializeObject<RootObject>(jsonData);
            }
            else
            {
                dbmcData = new RootObject();
            }

            dbmcData.UseJavaOptions = type;
            string updatedJsonData = JsonConvert.SerializeObject(dbmcData, Formatting.Indented);
            File.WriteAllText(launcherCore.ConfigFile, updatedJsonData);
        }

        private void UseUseMemory(int memory)
        {
            RootObject dbmcData;

            if (launcherCore.ConfigFileExists)
            {
                string jsonData = File.ReadAllText(launcherCore.ConfigFile);
                dbmcData = JsonConvert.DeserializeObject<RootObject>(jsonData);
            }
            else
            {
                dbmcData = new RootObject();
            }

            dbmcData.UseMemory = memory;
            string updatedJsonData = JsonConvert.SerializeObject(dbmcData, Formatting.Indented);
            File.WriteAllText(launcherCore.ConfigFile, updatedJsonData);
        }

        private void UpdateJavaPathInJson(string javaPath)
        {
            RootObject dbmcData;

            if (launcherCore.ConfigFileExists)
            {
                string jsonData = File.ReadAllText(launcherCore.ConfigFile);
                dbmcData = JsonConvert.DeserializeObject<RootObject>(jsonData);
            }
            else
            {
                dbmcData = new RootObject();
            }

            dbmcData.JavaPath = javaPath;

            string updatedJsonData = JsonConvert.SerializeObject(dbmcData, Formatting.Indented);

            File.WriteAllText(launcherCore.ConfigFile, updatedJsonData);
        }

        private void UpdateStartTopmost(bool startTopmost)
        {
            RootObject dbmcData;

            if (launcherCore.ConfigFileExists)
            {
                string jsonData = File.ReadAllText(launcherCore.ConfigFile);
                dbmcData = JsonConvert.DeserializeObject<RootObject>(jsonData);
            }
            else
            {
                dbmcData = new RootObject();
            }

            dbmcData.StartTopmost = startTopmost;

            string updatedJsonData = JsonConvert.SerializeObject(dbmcData, Formatting.Indented);

            File.WriteAllText(launcherCore.ConfigFile, updatedJsonData);
        }

        private void UpdateStartTools(bool startTools)
        {
            RootObject dbmcData;

            if (launcherCore.ConfigFileExists)
            {
                string jsonData = File.ReadAllText(launcherCore.ConfigFile);
                dbmcData = JsonConvert.DeserializeObject<RootObject>(jsonData);
            }
            else
            {
                dbmcData = new RootObject();
            }

            dbmcData.StartTools = startTools;

            string updatedJsonData = JsonConvert.SerializeObject(dbmcData, Formatting.Indented);

            File.WriteAllText(launcherCore.ConfigFile, updatedJsonData);
        }

        private void UpdateGameTips(bool gameTips)
        {
            RootObject dbmcData;

            if (launcherCore.ConfigFileExists)
            {
                string jsonData = File.ReadAllText(launcherCore.ConfigFile);
                dbmcData = JsonConvert.DeserializeObject<RootObject>(jsonData);
            }
            else
            {
                dbmcData = new RootObject();
            }

            dbmcData.GameTips = gameTips;

            string updatedJsonData = JsonConvert.SerializeObject(dbmcData, Formatting.Indented);

            File.WriteAllText(launcherCore.ConfigFile, updatedJsonData);
        }

        private void MemorySettings_UseSilder_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            MemorySettings_Use.Text = $"{Math.Round(MemorySettings_UseSilder.Value)} MB";
        }
    }
}
